﻿#include "FinsUdp.h"
#include <QRegularExpression>

#pragma execution_character_set("utf-8")
FinsUdp::FinsUdp(const QString& name, QObject *parent) 
    : PLCClientBase(name, parent)
{
    mConfig.type = PCT_FinsUdp;
    mConfig.comConfig.udp.mOpponentPort = 9600;
    mUdpClient = new UdpClient(this);
    connect(mUdpClient, &UdpClient::sigReceiveData, this, &FinsUdp::onReceiveData);
    connect(mUdpClient, &UdpClient::sigStateChanged, this, &FinsUdp::onStateChanged);

}

FinsUdp::~FinsUdp()
{
    if(mUdpClient)
        mUdpClient->onQuit();
}

void FinsUdp::onStateChanged(ComState state)
{
    setPLCState(state);
}
void FinsUdp::initCom()
{
    if(!mUdpClient)
        return;
    mUdpClient->setConfig(mConfig.comConfig);
    mUdpClient->onInit();
}

void FinsUdp::sendReadData(const PLCRequestData &data)
{
    mCurDataRead = data;
    QString command;
    switch(mCurDataRead.table){
    case QModbusDataUnit::HoldingRegisters:
        command = getReadHoldRegisterCommand(mCurDataRead.addrStart, mCurDataRead.getAddrSize());
        break;
    case QModbusDataUnit::Coils:
        command = getReadCoilsRegisterCommand(mCurDataRead.addrStart, mCurDataRead.getAddrSize());
        break;
    case QModbusDataUnit::InputRegisters:
        command = getReadCoilsRegisterCommand(mCurDataRead.addrStart, mCurDataRead.getAddrSize());
        break;
    default:
        break;
    }
    mUdpClient->onWrite(command);
}

void FinsUdp::sendWriteData(const PLCRequestData &data)
{
    mCurDataWrite = data;
    QString command;
    switch(mCurDataWrite.table){
    case QModbusDataUnit::HoldingRegisters:
        command = getWriteHoldRegisterCommand(mCurDataWrite.addrStart, mCurDataWrite.getAddrSize(), mCurDataWrite.data);
        break;
    case QModbusDataUnit::Coils:
        command = getWriteCoilsRegisterCommand(mCurDataWrite.addrStart, mCurDataWrite.getAddrSize(), mCurDataWrite.data);
        break;
    case QModbusDataUnit::InputRegisters:
        command = getWriteInputRegisterCommand(mCurDataWrite.addrStart, mCurDataWrite.getAddrSize(), mCurDataWrite.data);
        break;
    default:
        break;
    }
    mUdpClient->onWrite(command);
}

QString FinsUdp::getReadHoldRegisterCommand(int startAddr, int length)
{
    QString str="80000200";
    str += QString("%1").arg(mConfig.comConfig.udp.mOpponentIP.split('.').last().toInt(),2,16,QLatin1Char('0'));//PLCip最后一位/16进制
    str += "0000";
    str += QString("%1").arg(mConfig.comConfig.udp.mLocalIP.split('.').last().toInt(),2,16,QLatin1Char('0'));//pcip最后一位/16进制
    str += "0000";
    str += "0101";//读操作
    str += "82";
    str += QString("%1").arg(startAddr,4,16,QLatin1Char('0'));//起始地址
    str += "00";
    str += QString("%1").arg(length,4,16,QLatin1Char('0'));//读取长度
    return str;
}

QString FinsUdp::getReadCoilsRegisterCommand(int startAddr, int length)
{
    return "";

}

QString FinsUdp::getReadInputRegisterCommand(int startAddr, int length)
{
    return "";

}

QString FinsUdp::getWriteHoldRegisterCommand(int startAddr, int length, QList<ModbusValue> vData)
{
    QString str="80000200";
    str += QString("%1").arg(mConfig.comConfig.udp.mOpponentIP.split('.').last().toInt(),2,16,QLatin1Char('0'));//PLCip最后一位/16进制
    str += "0000";
    str += QString("%1").arg(mConfig.comConfig.udp.mLocalIP.split('.').last().toInt(),2,16,QLatin1Char('0'));//pcip最后一位/16进制
    str += "0000";
    str += "0102";//写操作
    str += "82";
    str += QString("%1").arg(startAddr,4,16,QLatin1Char('0'));//起始地址
    str += "00";
    str += QString("%1").arg(length,4,16,QLatin1Char('0'));//读取长度
    for(auto data : vData){
        if(data.valueType == VT_Bool){
            str += QString("%1").arg(data.valueI, 2, 16, QLatin1Char('0'));//读取长度
        } else if(data.valueType == VT_Int16){
            str += QString("%1").arg(data.valueI, 4, 16, QLatin1Char('0'));//读取长度
        } else if(data.valueType == VT_Int32){
            str += QString("%1").arg(data.valueDI, 8, 16, QLatin1Char('0'));//读取长度
        } else if(data.valueType == VT_Float){
            int32_t a = *((int*)(&(data.valueF)));
            str += QString("%1").arg(a, 8, 16, QLatin1Char('0'));//读取长度
        }
    }
    return str;
}

QString FinsUdp::getWriteCoilsRegisterCommand(int startAddr, int length, QList<ModbusValue> vData)
{
return "";
}

QString FinsUdp::getWriteInputRegisterCommand(int startAddr, int length, QList<ModbusValue> vData)
{
    return "";

}
//inline QList<qint16> FinsUdp::transToListInt(const QByteArray& buf)
//{
//    QList<qint16> intData = QList<qint16>();
//    for (int i = 0; i < buf.size(); i += 2){
//        QByteArray array;
//        array.resize(2);
//        array[0]=buf[i];
//        array[1]=buf[i+1];
//        intData << array.toHex().toInt(nullptr,16);
//    }
//    return intData;
//}
//inline QList<float> FinsUdp::transToListFloat(const QByteArray &data)
//{
//    QList<float> lstData;
//    //data[0]试数据的长度
//    for(int i = 1; i < data.size(); i += 4){
//        QByteArray arr = data.mid(i, 4);
//        if(false){
//            std::reverse(arr.begin(), arr.end());
//        }
//        float floatData;
//        memcpy(&floatData, arr.data(), arr.size());
//        lstData << floatData;
//    }
//    return lstData;
//}
void FinsUdp::onReceiveData(const QByteArray &data)
{
    if(data.size() > 14){
        PLCRequestData dataRev = mCurDataRead;
        QByteArray valueArray = data.mid(14);
        QList<ModbusValue> lstValue = dataRev.data;
        int index = 0;
        for(int i = 0; i < lstValue.size(); ++i){
            ValueType type = lstValue.at(i).valueType;
            if(type == VT_Bool){
                lstValue[i].valueI = valueArray.at(index);
                index += 1;
            } else if(type == VT_Int16){
                lstValue[i].valueI = byteArray2Int(valueArray.mid(index, 2));
                index += 2;
            } else if(type == VT_Int32){
                lstValue[i].valueI = byteArray2Int(valueArray.mid(index, 4));
                index += 4;
            } else if(type == VT_Float){
                lstValue[i].valueI = byteArray2Float(valueArray.mid(index, 4));
                index += 4;
            }
        }
        dataRev.data = lstValue;
        emit sigData(dataRev);
        processData(dataRev);
    }
}
